<template>
  <el-dialog
    v-model="dialogVisible"
    width="550"
    title="忘记密码"
    draggable
    destroy-on-close
    :show-close="true"
    :close-on-click-modal="false"
    custom-class="forgot-password-dialog"
  >
    <div class="dialog-body">
      <el-form
        ref="formRef"
        :model="formData"
        :rules="rules"
        label-position="top"
        label-width="120px"
        size="large"
      >
        <el-row style="margin-left: -10px; margin-right: -10px">
          <el-col :span="24" style="padding-left: 10px; padding-right: 10px">
            <el-form-item prop="tenantName">
              <el-input
                v-model="formData.username"
                @blur="getPhoneNumber"
                :maxlength="20"
                :placeholder="t('login.usernamePlaceholder')"
                :prefix-icon="iconHouse"
                type="primary"
                link
              />
            </el-form-item>
          </el-col>
          <el-col :span="24" style="padding-left: 10px; padding-right: 10px">
            <el-form-item prop="mobileNumber">
              <el-input
                v-model="formData.mobileNumber"
                :placeholder="t('login.mobileNumberPlaceholder')"
                :prefix-icon="iconCellphone"
                :readonly="true"
              />
            </el-form-item>
          </el-col>
          <el-col :span="24" style="padding-left: 10px; padding-right: 10px">
            <el-form-item prop="code">
              <el-row :gutter="5" justify="space-between" style="width: 100%">
                <el-col :span="24">
                  <el-input
                    v-model="formData.code"
                    :maxlength="6"
                    :placeholder="t('login.codePlaceholder')"
                    :prefix-icon="iconCircleCheck"
                  >
                    <template #append>
                      <el-button
                        type="primary"
                        :disabled="isCode"
                        :prefix-icon="iconCircleCheck"
                        @click="getSmsCode()"
                        >{{ validMess }}</el-button
                      >
                    </template>
                  </el-input>
                </el-col>
              </el-row>
            </el-form-item>
          </el-col>
          <el-col :span="24" style="padding-left: 10px; padding-right: 10px">
            <el-form-item prop="newPassword">
              <el-row :gutter="5" justify="space-between" style="width: 100%">
                <el-col :span="24">
                  <el-input
                    type="password"
                    :maxlength="16"
                    show-password
                    autocomplete="new-password"
                    v-model="formData.newPassword"
                    :placeholder="t('login.passwordPlaceholder')"
                    :prefix-icon="iconLock"
                  >
                  </el-input>
                </el-col>
              </el-row>
            </el-form-item>
          </el-col>
          <el-col :span="24" style="padding-left: 10px; padding-right: 10px">
            <el-form-item prop="againPassword">
              <el-row :gutter="5" justify="space-between" style="width: 100%">
                <el-col :span="24">
                  <el-input
                    type="password"
                    :maxlength="16"
                    show-password
                    autocomplete="new-password"
                    v-model="formData.againPassword"
                    :placeholder="t('login.passwordAgainPlaceholder')"
                    :prefix-icon="iconLock"
                  >
                  </el-input>
                </el-col>
              </el-row>
            </el-form-item>
          </el-col>
        </el-row>
      </el-form>
    </div>
    <template #footer>
      <div class="footer">
        <el-button type="primary" @click="submitForm" class="w-full"> 提交 </el-button>
      </div>
    </template>
  </el-dialog>
</template>
<script lang="ts" setup>
import * as LoginApi from '@/api/login'
import * as register from '@/api/register'
import { useIcon } from '@/hooks/web/useIcon'
import { cloneDeep } from 'lodash'

const emit = defineEmits(['success'])
const formRef = ref()
const { t } = useI18n()
const message = useMessage()
const validMess = ref('获取验证码')
const dialogVisible = ref(false)
const dialogTitle = ref('')
const formData = ref({
  username: undefined,
  mobileNumber: undefined,
  code: undefined,
  newPassword: undefined,
  againPassword: undefined
})
let isCode = ref(false)
let countNum = ref(59)
let intervalId = null as any

const countNumFun = () => {
  if (countNum.value <= 0) {
    clearInterval(intervalId)
    countNum.value = 59
    isCode.value = false
    validMess.value = '获取验证码'
    return
  }
  countNum.value -= 1
  isCode.value = true
  validMess.value = countNum.value + '秒'
}

const isSameNewPassword = (rule, value, callback) => {
  if (!formData.value.newPassword) {
    return callback()
  }
  if (value !== formData.value.newPassword) {
    callback(new Error('再次输入密码与新密码不一致'))
  } else {
    callback()
  }
}

const validateString = (rule, value, callback) => {
  if (
    /^((?=.*[A-Za-z])(?=.*\d)|(?=.*[A-Za-z])(?=.*[!@#$%^&*()_+\-\=])|(?=.*\d)(?=.*[!@#$%^&*()_+\-\=]))[A-Za-z\d!@#$%^&*()_+\-\=]{6,16}$/.test(
      value
    )
  ) {
    return callback()
  } else {
    return callback(new Error('至少包含字母数字特殊字符两种以上'))
  }
}

const rules = reactive({
  username: [{ required: true, message: '用户账号不能为空', trigger: 'blur' }],
  code: [{ required: true, message: '验证码不能为空', trigger: 'blur' }],
  newPassword: [
    { required: true, message: '密码不能为空', trigger: 'blur' },
    { min: 6, max: 16, message: '密码长度6-16位', trigger: 'blur' },
    { validator: validateString, trigger: 'blur' }
  ],
  againPassword: [
    { required: true, message: '再次输入密码不能为空', trigger: 'blur' },
    { validator: isSameNewPassword, trigger: 'blur' }
  ]
})
const formLoading = ref(false)
const iconHouse = useIcon({ icon: 'ep:user' })
const iconCellphone = useIcon({ icon: 'ep:iphone' })
const iconCircleCheck = useIcon({ icon: 'ep:circle-check' })
const iconLock = useIcon({ icon: 'ep:lock' })

const open = async (username?) => {
  dialogVisible.value = true
  dialogTitle.value = '忘记密码'
  resetFn()
  if (username) {
    formData.value.username = username
    getPhoneNumber()
  }
}

const getPhoneNumber = async () => {
  if (!formData.value.username) {
    return
  }
  try {
    const data = {
      username: formData.value.username
    }
    const res = await LoginApi.getUserByUsername(data)
    formData.value.mobileNumber = res.mobile
  } catch {
    formData.value.mobileNumber = undefined
  }
}

const getSmsCode = async () => {
  if (!formData.value.mobileNumber) {
    message.warning(t('warn.noPhone'))
    return
  }
  try {
    formLoading.value = true
    const res = await register.sendSmsCode({
      mobile: formData.value.mobileNumber,
      scene: 6
    })
    if (res) {
      ElNotification({
        title: '验证码信息',
        dangerouslyUseHTMLString: true,
        duration: 10000,
        message: res
      })
    }
    message.success(t('common.sendSuccess'))
    validMess.value = countNum.value + '秒'
    intervalId = setInterval(() => {
      countNumFun()
    }, 1000)
  } finally {
    formLoading.value = false
  }
}

const submitForm = async () => {
  if (!formRef) return
  const valid = await formRef.value.validate()
  if (!valid) return
  try {
    formLoading.value = true
    const data = cloneDeep(formData.value)
    delete data.mobileNumber
    delete data.againPassword
    await LoginApi.forgetPassword(data)
    message.success(t('common.operateSuccess'))
    dialogVisible.value = false
  } finally {
    formLoading.value = false
  }
}

const resetFn = () => {
  formData.value = {
    username: undefined,
    mobileNumber: undefined,
    code: undefined,
    newPassword: undefined,
    againPassword: undefined
  }
}

defineExpose({ open })
</script>

<style lang="scss" scoped>
.footer {
  padding: 0 116px;
}

.dialog-body {
  padding: 0 116px;
}
</style>

<style lang="scss">
.forgot-password-dialog {
  .el-dialog__header {
    text-align: center !important;
    font-weight: bold !important;
  }
}
</style>
